#include "server.h"

POOL *threadPoolInit(void)
{
	return pool_init(10, 20);
}

sqlite3 *dataBaseInit(void)
{
	char cfgBuf[20] = {0};
	int rtn = 0;
	int cfgFD = 0;

	Mesg rootUsr = {
		.type = 0,
		.name = "feiyang",
		.work_num = "000",
		.passwd = "000",
	};

	sqlite3 * dbEntry = open_mydb(DBPATH);
	rtn = create_table(dbEntry);

	cfgFD = open(SVRCFG, O_RDWR | O_CREAT, 0777);
	if (cfgFD < 0)
	{
		perror("open config file");
		exit(-1);
	}
	rtn = read(cfgFD, cfgBuf, sizeof(cfgBuf));
	if (rtn == 0)
	{
		write(cfgFD, "server configed", 15);
		rtn = inset_user(dbEntry, &rootUsr);
		if (rtn == -1) exit(-1);
	}
	else if (rtn > 0)
	{
		close(cfgFD);
		/* 管理员信已息创建 */
		if (0 == strncmp("server configed", cfgBuf, 15))
		{
			return dbEntry;	
		}
	}
	/* 管理员信息加载异常 */
	else
	{
		close(cfgFD);
		exit(-1);
	}
}

void mainThread(POOL *pool, sqlite3 *dbEntry)
{
	int listenFD = socket(AF_INET, SOCK_STREAM, 0);
	if (listenFD < 0)
	{
		perror("create listen socket");
		exit(-1);
	}
	struct sockaddr_in serverAddr = {0};
	struct sockaddr_in clientAddr = {0};
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(2016);
	serverAddr.sin_addr.s_addr = inet_addr("0.0.0.0"); /* Listen eth? */

	if (-1 == bind(listenFD, (struct sockaddr*)&serverAddr, sizeof(serverAddr)))
	{
		perror("bind listen socket");
		exit(-1);
	}
	if(-1 == listen(listenFD, 10))
	{
		perror("listen client");
	}

	int len = 0;
	while(1)
	{
		int clientFD = accept(listenFD, (struct sockaddr *)&clientAddr, &len);
		if (-1 == clientFD)
		{
			perror("accetp client");
			continue;
		}
		printf("\033[1;32;40m[%02d]\033[0m New client \033[1;32;40mconnect\033[0m   \033[1;32;40m%s\033[0m <ip>\n",
				clientFD, inet_ntoa(clientAddr.sin_addr));
		
		CLIENT_T *newClient = (CLIENT_T *)malloc(sizeof (CLIENT_T));
		if (newClient == NULL)
		{
			perror("client parameter malloc");
			close(clientFD);
			continue;
		}
		bzero(newClient, sizeof(CLIENT_T));
		newClient->dbEntry = dbEntry;
		newClient->clientFD = clientFD;
		pool_add_task(pool, threadTask, (void *)newClient);
	}
	close(listenFD);
}

void *threadTask(void *argv)
{
	CLIENT_T *clientHandle = (CLIENT_T *)argv;
	Mesg message;
	int rtn = 0;
	while(1)
	{
		rtn = read(clientHandle->clientFD, &message, sizeof(Mesg));
		if (rtn < 0)
		{
			perror("read from client");
		}
		else if (rtn == 0) goto done;
		printf("\033[1;34;40m[%02d]\033[0m \033[1;34;40mreceive\033[0m   \033[1;34;40m%d\033[0m <type>   \033[1;34;40m%d\033[0m <cmd>   \033[1;34;40m%d\033[0m <ack>\n", 
				clientHandle->clientFD, message.type, message.cmd, message.ack);

		switch(message.cmd)
		{
		case LOGIN:
			rtn = loginDeal(clientHandle->dbEntry, &message);
			break;
		case REG:
			rtn = registerDeal(clientHandle->dbEntry, &message);
			break;
		case CATU:
			rtn = catUserInfoDeal(clientHandle->dbEntry, &message);
			break;
		case UPPWD:
			rtn = updatePasswdDeal(clientHandle->dbEntry, &message);
			break;
		case UPU:
			rtn = updateUserInfoDeal(clientHandle->dbEntry, &message);
			break;
		case DELU:
			rtn = deleteUserDeal(clientHandle->dbEntry, &message);
			break;
		default:
			break;
		}
		/* 数据库操作异常 */
		if (rtn < 0)
		{
			message.ack = DBERR;
			goto done;
		}
		/* 向客户端发送结果 */
		rtn = write(clientHandle->clientFD, &message, sizeof(message));
		if (rtn < 0)
		{
			goto done;

		}
		printf("\033[1;36;40m[%02d]\033[0m \033[1;36;40msend\033[0m      \033[1;36;40m%d\033[0m <type>   \033[1;36;40m%d\033[0m <cmd>   \033[1;36;40m%d\033[0m <ack>\n", 
				clientHandle->clientFD, message.type, message.cmd, message.ack);
	}
done:
	printf("\033[1;31;40m[%02d]\033[0m client \033[1;31;40mdisconnect\033[0m\n", clientHandle->clientFD);
	close(clientHandle->clientFD);
	free(clientHandle);
}

void resourceRcycle(POOL *pool, sqlite3 *dbEntry)
{
	destroy_pool(pool);
	close_mydb(dbEntry);
}
